package tk.xboot.boot.bean;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 *
 */

@Slf4j
@Intercepts({
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
@Component
public class MyBatisPerfInterceptor implements Interceptor {
    private static final String GLOBAL_METRIC_NAME = "ibatis_mapper_method";
    private static final String GLOBAL_METRIC_NAME_CPUTIME = "ibatis_mapper_method_cputime";
    private Properties properties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        String mapperId = "unknownMapperId";
        String className = "unknownClass";
        String methodName = "unknownMethod";
        String sqlType = "unknownType";
        try {
            MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
            mapperId = mappedStatement.getId();
            String[] segments = mapperId.split("\\.");
            className = segments[segments.length - 2];
            methodName = segments[segments.length - 1];
            sqlType = mappedStatement.getSqlCommandType().name();
        } catch (Exception e) {
            log.error("failed to capture mybatis method name : {}", mapperId, e);
        }

        long start = System.currentTimeMillis();
        Object res = invocation.proceed();
        long end = System.currentTimeMillis();
        log.info("mapper id {} ,cost {} sec", mapperId, end - start);
        return res;
    }

    @Override
    public Object plugin(Object target) {
        return null;
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
